<?php

namespace App\Kuafu\Sys\Service;

use App\Kuafu\Base\Enum\BaseCodeEnum;
use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Sys\Enum\SysCacheEnum;
use App\Kuafu\Sys\Exceptions\SysException;
use App\Kuafu\Sys\Model\Menus;
use App\Kuafu\Sys\Validate\MenusValidate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class MenusService extends BaseService
{
    /**
     * 添加菜单
     *
     * @param $request
     * @return array
     */
    public static function addMenu(Request $request): bool
    {
        $valid = MenusValidate::addMenus($request->all());
        if ($valid) {
            throw new SysException(BaseCodeEnum::ERR_SYSTEM_MENUS_PARAM, $valid);
        }

        $menus           = new Menus();
        $menus->name     = $request->name;
        $menus->url      = $request->url;
        $menus->parentId = $request->parentId;
        $menus->type     = $request->type;
        $menus->locate   = $request->post('locate', 0);
        $menus->status   = 0;

        if (!$menus->save()) {
            throw new SysException(BaseCodeEnum::ERR_DB_ERROR);
        }

        Cache::forget(SysCacheEnum::getSysMenuList());

        return true;
    }

    /**
     * 菜单详情
     *
     * @param $request
     * @return array
     */
    public static function getMenuInfo(Request $request): array
    {
        $info = Menus::query()
                     ->where("id", $request->get('id', 0))
                     ->first(['id', 'name', 'url', 'parentId', 'type', 'status', 'locate']);

        if (!$info) {
            throw new SysException(BaseCodeEnum::ERR_DB_ERROR);
        }

        $return = $info->toArray();

        return $return;
    }

    /**
     * 获取菜单列表
     *
     * @param $request
     * @return array
     */
    public static function getMenuList()
    {
        $list = Menus::getAll();

        $list = self::formatMenus($list->toArray());

        return $list;
    }

    /**
     * 获取所有 Web 端的菜单列表
     *
     * @return Menus[]|\Illuminate\Database\Eloquent\Collection
     */
    public static function getWebMenusList()
    {
        $list = Menus::getAll(Menus::TYPE_WEB);

        return $list;
    }

    /**
     * 获取所有 POS 端的菜单列表
     *
     * @return Menus[]|\Illuminate\Database\Eloquent\Collection
     */
    public static function getPosMenusList()
    {
        $list = Menus::getAll(Menus::TYPE_POS);

        return $list;
    }

    /**
     * 编辑菜单
     * @param $request
     * @return bool|mixed
     */
    public static function setMenu(Request $request)
    {
        $valid = MenusValidate::addMenus($request->all());

        if ($valid) {
            throw new SysException(BaseCodeEnum::ERR_SYSTEM_MENUS_PARAM, $valid);
        }


        $obj = Menus::query()->find($request->post('menuId'));

        if (empty($obj)) {
            throw new SysException(
                BaseCodeEnum::ERR_SYSTEM_MENUS_PARAM_MENU_ID,
                BaseCodeEnum::CODE_TEXT[BaseCodeEnum::ERR_SYSTEM_MENUS_PARAM_MENU_ID]
            );
        }

        $obj->name     = $request->name;
        $obj->url      = $request->url;
        $obj->parentId = $request->parentId;
        $obj->type     = $request->type;
        $obj->locate   = $request->post('locate', 0);
        $obj->status   = $request->status;

        if (!$obj->save()) {
            throw new SysException(BaseCodeEnum::ERR_SYSTEM_MENUS_EDIT,
                BaseCodeEnum::CODE_TEXT[BaseCodeEnum::ERR_SYSTEM_MENUS_EDIT]);
        }

        Cache::forget(SysCacheEnum::getSysMenuList());

        return true;
    }

    /**
     * 删除菜单
     *
     * @param $request
     * @return array
     */
    public static function deletedMenu(Request $request): bool
    {
        $obj = Menus::query()->find($request->post('menuId'));

        if (empty($obj)) {
            throw new SysException(
                BaseCodeEnum::ERR_SYSTEM_MENUS_PARAM_MENU_ID,
                BaseCodeEnum::CODE_TEXT[BaseCodeEnum::ERR_SYSTEM_MENUS_PARAM_MENU_ID]
            );
        }

        // 判断是否能删除
        $otherObj = Menus::query()->where('parentId', $obj->id)->first();
        if (!empty($otherObj)) {
            throw new SysException(
                BaseCodeEnum::ERR_SYSTEM_MENUS_DELETE_ONE,
                BaseCodeEnum::CODE_TEXT[BaseCodeEnum::ERR_SYSTEM_MENUS_DELETE_ONE]
            );
        }

        $obj->isDeleted = 1;

        if (!$obj->save()) {
            throw new SysException(
                BaseCodeEnum::ERR_SYSTEM_MENUS_DEL,
                BaseCodeEnum::CODE_TEXT[BaseCodeEnum::ERR_SYSTEM_MENUS_DEL]
            );
        }

        Cache::forget(SysCacheEnum::getSysMenuList());

        return true;
    }

    /**
     * 整理无限极分类
     *
     * @param array $list
     * @return array
     */
    public static function formatMenus($data, $pId = 0, $rootId = 0)
    {
        $tree = [];
        foreach ($data as $k => $v) {
            if ($v['parentId'] == $pId) {
                $v['children'] = self::formatMenus($data, $v['id'], $rootId ?: $v['parentId']);
                $v['rootId']   = $rootId ?: $v['parentId'];
                $tree[]        = $v;
            }
        }
        return $tree;
    }

    /**
     * 删除没权限的无限极分类
     *
     * @param array $list
     * @return array
     */
    public static function filterNoAccessMenus(&$data)
    {
        self::filterNoAccessMenusTwice($data);

        $data = array_values($data);
        foreach ($data as $key => $value) {
            if (empty($value['permissionList']) && empty($value['children'])) {
                unset($data[$key]);
            }
        }
        $data = array_values($data);
    }

    public static function filterNoAccessMenusTwice(&$data)
    {
        foreach ($data as $dataKey => &$dataValue) {
            if (!empty($dataValue['children'])) {
                self::filterNoAccessMenus($dataValue['children']);
            } else {
                if (empty($dataValue['permissionList']) && empty($dataValue['children'])) {
                    unset($data[$dataKey]);
                }
            }
        }
    }
}
